package ui;

import dal.Conexion;
import dal.Configuracion;
import dto.Tabla;
import factory.FactoryDao;
import generator.Generador;
import generator.GeneradorMySQL;
import generator.GeneradorPostgreSQL;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

/**
 *
 * @author Jose Carlos Gutierrez
 */
public class WinPrincipal extends javax.swing.JFrame {

    private Vector<Tabla> tablas;

    /** Creates new form WinPrincipal */
    public WinPrincipal() {
        initComponents();
        setJMenuBar(getBarraMenu());
        nuevo();
        setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setResizable(false);
    }

    private void nuevo() {
        listTablas.removeAll();
        listTablas.validate();
        listTablas.updateUI();
        tfUsuario.setText("");
        tfPuerto.setText("");
        tfServidor.setText("");
        tfPassword.setText("");
        tfInstancia.setText("");
        tfNombre.setText("");
        tfPath.setText("");
        btnGenerar.setEnabled(false);
        btnPath.setEnabled(false);
        tablas = new Vector<Tabla>();
    }

    private JMenuBar getBarraMenu() {
        JMenuBar bar = new JMenuBar();

        JMenu menu = new JMenu("Opciones");
        JMenuItem item = new JMenuItem("Nuevo       ");
        item.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                nuevo();
            }
        });
        menu.add(item);

        item = new JMenuItem("Salir");
        item.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        menu.add(item);

        bar.add(menu);
        return bar;
    }

    private void mensaje(String msg) {
        JOptionPane.showMessageDialog(this, msg);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        pnlConexion = new javax.swing.JPanel();
        lbSQLServer = new javax.swing.JLabel();
        tfServidor = new javax.swing.JTextField();
        lbServidor = new javax.swing.JLabel();
        lbInstancia = new javax.swing.JLabel();
        lbPassword = new javax.swing.JLabel();
        tfPassword = new javax.swing.JTextField();
        lbUsuario = new javax.swing.JLabel();
        tfUsuario = new javax.swing.JTextField();
        tfInstancia = new javax.swing.JTextField();
        lbTablas = new javax.swing.JLabel();
        jspTablas = new javax.swing.JScrollPane();
        listTablas = new javax.swing.JList();
        btnConectar = new javax.swing.JButton();
        lbBaseDatos = new javax.swing.JLabel();
        cbBaseDatos = new javax.swing.JComboBox();
        tfNombre = new javax.swing.JTextField();
        lbNombre = new javax.swing.JLabel();
        tfPuerto = new javax.swing.JTextField();
        lbPuerto = new javax.swing.JLabel();
        pnlGeneracion = new javax.swing.JPanel();
        lbPath = new javax.swing.JLabel();
        tfPath = new javax.swing.JTextField();
        btnPath = new javax.swing.JButton();
        btnGenerar = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        pnlConexion.setBorder(javax.swing.BorderFactory.createTitledBorder("Datos de Conexion"));

        lbSQLServer.setForeground(new java.awt.Color(102, 102, 102));
        lbSQLServer.setText("(SQL Server)");

        tfServidor.setToolTipText("");

        lbServidor.setText("Servidor:");

        lbInstancia.setText("Instancia:");

        lbPassword.setText("Contraseña:");

        tfPassword.setToolTipText("");

        lbUsuario.setText("Usuario:");

        tfUsuario.setToolTipText("");

        tfInstancia.setToolTipText("");

        lbTablas.setText("Tablas");

        jspTablas.setViewportView(listTablas);

        btnConectar.setText("Conectar");
        btnConectar.setToolTipText("Conectar");
        btnConectar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConectarActionPerformed(evt);
            }
        });

        lbBaseDatos.setText("Base De Datos");
        lbBaseDatos.setToolTipText("");

        cbBaseDatos.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "MySQL", "PostgreSQL" }));
        cbBaseDatos.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cbBaseDatosItemStateChanged(evt);
            }
        });

        tfNombre.setToolTipText("");

        lbNombre.setText("Nombre de la Base de Datos:");

        tfPuerto.setToolTipText("");

        lbPuerto.setText("Puerto");
        lbPuerto.setToolTipText("");

        javax.swing.GroupLayout pnlConexionLayout = new javax.swing.GroupLayout(pnlConexion);
        pnlConexion.setLayout(pnlConexionLayout);
        pnlConexionLayout.setHorizontalGroup(
            pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlConexionLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlConexionLayout.createSequentialGroup()
                            .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                    .addComponent(lbUsuario, javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(lbPassword, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(lbInstancia, javax.swing.GroupLayout.Alignment.LEADING))
                                .addComponent(lbNombre))
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))
                        .addGroup(pnlConexionLayout.createSequentialGroup()
                            .addComponent(lbPuerto)
                            .addGap(111, 111, 111)))
                    .addComponent(lbServidor)
                    .addComponent(lbBaseDatos))
                .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnlConexionLayout.createSequentialGroup()
                        .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(tfServidor, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
                            .addComponent(tfPassword, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
                            .addComponent(tfUsuario, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
                            .addComponent(tfInstancia, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
                            .addComponent(tfNombre, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
                            .addComponent(tfPuerto, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
                            .addComponent(cbBaseDatos, 0, 162, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lbSQLServer)
                        .addGap(7, 7, 7))
                    .addGroup(pnlConexionLayout.createSequentialGroup()
                        .addComponent(btnConectar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lbTablas)
                    .addComponent(jspTablas, javax.swing.GroupLayout.PREFERRED_SIZE, 288, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        pnlConexionLayout.setVerticalGroup(
            pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlConexionLayout.createSequentialGroup()
                .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lbTablas)
                    .addComponent(cbBaseDatos, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lbBaseDatos))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(pnlConexionLayout.createSequentialGroup()
                        .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(tfServidor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lbServidor))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lbPuerto)
                            .addComponent(tfPuerto, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(tfUsuario, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lbUsuario))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(tfPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lbPassword))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(tfInstancia, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lbInstancia)
                            .addComponent(lbSQLServer))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlConexionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(tfNombre, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lbNombre))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(btnConectar))
                    .addComponent(jspTablas))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pnlGeneracion.setBorder(javax.swing.BorderFactory.createTitledBorder("Datos de Generacion"));

        lbPath.setText("Carpeta:");

        tfPath.setEditable(false);
        tfPath.setToolTipText("");

        btnPath.setText("Examinar...");
        btnPath.setToolTipText("Examinar...");
        btnPath.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPathActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout pnlGeneracionLayout = new javax.swing.GroupLayout(pnlGeneracion);
        pnlGeneracion.setLayout(pnlGeneracionLayout);
        pnlGeneracionLayout.setHorizontalGroup(
            pnlGeneracionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlGeneracionLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lbPath)
                .addGap(18, 18, 18)
                .addComponent(tfPath)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnPath)
                .addContainerGap())
        );
        pnlGeneracionLayout.setVerticalGroup(
            pnlGeneracionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlGeneracionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(lbPath)
                .addComponent(tfPath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(btnPath))
        );

        btnGenerar.setText("Generar");
        btnGenerar.setToolTipText("Generar");
        btnGenerar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnGenerarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pnlGeneracion, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(pnlConexion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(302, 302, 302)
                                .addComponent(btnGenerar)))
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pnlConexion, javax.swing.GroupLayout.PREFERRED_SIZE, 264, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(pnlGeneracion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(16, 16, 16)
                .addComponent(btnGenerar)
                .addGap(27, 27, 27))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPathActionPerformed
        JFileChooser chooser = new JFileChooser();
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int option = chooser.showOpenDialog(this);
        if (option == JFileChooser.APPROVE_OPTION) {
            File selectedFile = chooser.getSelectedFile();
            tfPath.setText(selectedFile.getAbsolutePath());
            tfPath.setToolTipText(tfPath.getText());
            btnGenerar.setEnabled(true);
        }

}//GEN-LAST:event_btnPathActionPerformed

    private void btnConectarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConectarActionPerformed
        btnGenerar.setEnabled(false);
        btnPath.setEnabled(false);
        //tfPath.setText("");
        String dataBase = cbBaseDatos.getSelectedItem().toString();
        String servidor = tfServidor.getText();
        String usuario = tfUsuario.getText();
        String password = tfPassword.getText();
        String instancia = tfInstancia.getText();
        String nombre = tfNombre.getText();
        String puerto = tfPuerto.getText();

        if (servidor.trim().equals("")) {
            mensaje("Ingrese el nombre del Servidor");
            tfServidor.grabFocus();
            return;
        }

        if (usuario.trim().equals("")) {
            mensaje("Ingrese el usuario");
            tfUsuario.grabFocus();
            return;
        }

        if (password.trim().equals("")) {
            mensaje("Ingrese el password");
            tfPassword.grabFocus();
            return;
        }

        if (dataBase.equals("SQL Server") && instancia.trim().equals("")) {
            mensaje("Ingrese el nombre de la instancia de la Base de Datos");
            tfInstancia.grabFocus();
            return;
        }

        if (nombre.trim().equals("")) {
            mensaje("Ingrese el nombre de la Base de Datos");
            tfNombre.grabFocus();
            return;
        }

        Configuracion config = Configuracion.getConfiguracion();
        config.setDbEngine(dataBase);
        config.setDbHost(servidor);
        config.setDbInstace(instancia);
        config.setDbUser(usuario);
        config.setDbPassword(password);
        config.setDbName(nombre);
        config.setDbPort(puerto);

        try {
            listTablas.removeAll();
            factory.FactoryDao factory = FactoryDao.getFactoryInstance();
            dao.TablaDao dao = factory.getNewTablaDao();
            Vector<Tabla> vector = dao.selectTodos();
            if (vector == null) {
                mensaje("Ha ocurrido un error en la conexion a la Base de Datos");
                Conexion.getOrCreate().desconectar();
                return;
            }
            Iterator<Tabla> iterador = vector.iterator();
            while (iterador.hasNext()) {
                Tabla tabla = iterador.next();
                tabla.setColumnas(FactoryDao.getFactoryInstance().getNewColumnaDao().select(tabla.getNombreTabla()));
            }
            listTablas.setListData(vector);
            listTablas.validate();
            listTablas.updateUI();
            btnPath.setEnabled(true);
            tablas = vector;
        } catch (Exception ex) {
            mensaje("Ha ocurrido un error en la conexion a la Base de Datos");
        }
    }//GEN-LAST:event_btnConectarActionPerformed

    private void cbBaseDatosItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbBaseDatosItemStateChanged
        tfInstancia.setEnabled(cbBaseDatos.getSelectedItem().toString().equals("SQL Server"));
        tfInstancia.setText("");
    }//GEN-LAST:event_cbBaseDatosItemStateChanged

    private void btnGenerarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGenerarActionPerformed
        Generador objGenerador = null;
        if (cbBaseDatos.getSelectedItem().toString().equals("MySQL")) {
            objGenerador = new GeneradorMySQL(tfPath.getText());

        }
        if (cbBaseDatos.getSelectedItem().toString().equals("PostgreSQL")) {
            objGenerador = new GeneradorPostgreSQL(tfPath.getText());
        }
        if(objGenerador == null){
            mensaje("No se pudo construir el generador");
            return;
        }
        objGenerador.generar(tablas);
        mensaje("Gerneacion Finalizada!");
    }//GEN-LAST:event_btnGenerarActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        new WinPrincipal().setVisible(true);
    }

    static {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnConectar;
    private javax.swing.JButton btnGenerar;
    private javax.swing.JButton btnPath;
    private javax.swing.JComboBox cbBaseDatos;
    private javax.swing.JScrollPane jspTablas;
    private javax.swing.JLabel lbBaseDatos;
    private javax.swing.JLabel lbInstancia;
    private javax.swing.JLabel lbNombre;
    private javax.swing.JLabel lbPassword;
    private javax.swing.JLabel lbPath;
    private javax.swing.JLabel lbPuerto;
    private javax.swing.JLabel lbSQLServer;
    private javax.swing.JLabel lbServidor;
    private javax.swing.JLabel lbTablas;
    private javax.swing.JLabel lbUsuario;
    private javax.swing.JList listTablas;
    private javax.swing.JPanel pnlConexion;
    private javax.swing.JPanel pnlGeneracion;
    private javax.swing.JTextField tfInstancia;
    private javax.swing.JTextField tfNombre;
    private javax.swing.JTextField tfPassword;
    private javax.swing.JTextField tfPath;
    private javax.swing.JTextField tfPuerto;
    private javax.swing.JTextField tfServidor;
    private javax.swing.JTextField tfUsuario;
    // End of variables declaration//GEN-END:variables
}
